/*SPI routines*/
#ifndef SPI_H
#define SPI_H

/* Scheduler include files. */
#include "FreeRTOS.h"
#include "task.h"
#include "semphr.h"

/*Header File*/
#include "..\common\errcode.h"
#include "..\common\osdata.h"

/*Device specific headers*/
#include <AT91SAM7S64.H>
#include <lib_AT91SAM7S64.h>

/*Configurations*/
#define SPI_SENDRCV_DIS_W_SETTING   0 //The SPI PDC is temporarily disabled while configuring to send / receive

/*Definitions*/	
#define SPI_MIN_DIVIDER 2

/*IO Ports definition*/
/*CS0 only in PA11*/
#define SPI_IO_CS0  (unsigned int) AT91C_PA11_NPCS0
/*CS1 in PA31 or in PA9*/
#if SELECT_SPI_IO_CS1 == PA31
#define SPI_IO_CS1 (unsigned int) AT91C_PA31_NPCS1
#else
#define SPI_IO_CS1 (unsigned int) AT91C_PA9_NPCS1
#endif
/*CS2 in PA30 or in PA10*/
#if SELECT_SPI_IO_CS2 == PA30
#define SPI_IO_CS2 (unsigned int) AT91C_PA30_NPCS2
#else
#define SPI_IO_CS2 (unsigned int) AT91C_PA10_NPCS2
#endif
/*CS3 in PA3, PA5 or PA22*/
#if SELECT_SPI_IO_CS2 == PA3
#define SPI_IO_CS3 (unsigned int) AT91C_PA3_NPCS3
#elif SELECT_SPI_IO_CS2 == PA5
#define SPI_IO_CS3 (unsigned int) AT91C_PA5_NPCS3
#else
#define SPI_IO_CS3 (unsigned int) AT91C_PA22_NPCS3
#endif

/*enumerations*/
//Error codes for SPI initialization
typedef enum
{
	spiInitSuccess = 0,
    spiInitMaxCs
} eSpiInitError;

typedef enum
{
	ChipSelect0 = 0,
    ChipSelect1 = 1,
    ChipSelect2 = 2,
    ChipSelect3 = 3,
    ChipSelectMax
} eCSDevice;

/*Types Definition, unions*/
#pragma anon_unions

typedef struct
{
	eCSDevice device;
    unsigned portCHAR clockDivider;
	unsigned portSHORT sizeR;
	unsigned portSHORT sizeW;
	unsigned portCHAR *dataR;
    const unsigned portCHAR *dataW;
	portTickType xBlockTime;
} tSpiRWdata, *pSpiRWdata;

typedef struct
{
    struct {unsigned portCHAR dev_1_Enabled:1, dev_2_Enabled:1, dev_3_Enabled:1, dev_4_Enabled:1, :4; };    
    tOSData  mutex, event;
} tSpiPort;

/*Constants*/

/*Variable Definition*/
extern tSpiPort spiPort;

/*Functionality enabling*/

/*Public Functions and procedures Declaration*/
void spiHandleCS(eCSDevice device, unsigned portCHAR status);
eSpiInitError eSpiInit(eCSDevice device);
unsigned portCHAR cSpiReadWrite(pSpiRWdata pData);
unsigned portCHAR ucGetCurrentSpeed(int cs);
void vSpiClose(eCSDevice device);
void vSpiISR(void);
extern void vSpiISREntry( void ); //Interrupt entry point written in the assembler file spiISR.s
/*Macro definitions*/

#endif //SPI_H
